#include "stdafx.h"

CSocketIcmpPool::CSocketIcmpPool()
{
	_id = 1;
	_seq = 1;
}


CSocketIcmpPool::~CSocketIcmpPool()
{
	m_Socketlist.clear();
}

void CSocketIcmpPool::get_idseq(uint16_t &xid, uint16_t &seq)
{
	if (_id == 0xFFFF)
		_id = 1;
	if (_seq == 0xFFFF)
	{
		_id++;
		_seq = 1;
	}
	_lock.lock();
	xid = sock_htons(_id);
	seq = sock_htons(_seq++);
	_lock.unlock();
	return;
}

bool CSocketIcmpPool::processRx(uint32_t remoteip, uint16_t xid, uint16_t xseq, uint8_t ttl)
{
	auto time32 = (uint32_t)getTime();
	CSocketIcmp *client = nullptr;
	uint32_t handle = (xid << 16)&0xFFFF0000;
	handle |= xseq;
	LOG_DEBUG("%08x\r\n", handle);
	_lock.lock();
	auto ptr = m_Socketlist.find((HANDLE)((ULONG_PTR)handle));
	if (ptr!=m_Socketlist.end())
	{
		client = ptr->second;
	}
	_lock.unlock();
	if (client)
	{
		client->ProcessRx(ttl, time32, remoteip);
		return true;
	}
	return false;
}

HANDLE CSocketIcmpPool::regClass(CSocketIcmp *_this,uint32_t handle)
{
	if (handle < (uint32_t)0xFFFFFFFF)
	{
		_lock.lock();
		m_Socketlist[(HANDLE)((ULONG_PTR)handle)] = _this;
		_lock.unlock();
		return (HANDLE)((ULONG_PTR)handle);
	}
	return INVALID_HANDLE_VALUE;
}

void CSocketIcmpPool::unregClass(HANDLE _handle)
{
	_lock.lock();
	auto ptr = m_Socketlist.find(_handle);
	if (ptr!=m_Socketlist.end())
	{
		m_Socketlist.erase(ptr);
	}
	_lock.unlock();
}